#!/usr/bin/env python
# -*- coding:utf-8 -*-
#1.简述面向对象三大特性并用代码表示。
'''
封装，继承，多态

#封装,将数据封装到对象
class Func:
    def __init__(self,name,age):
        self.name=name
        self.age=age

obj=Func('梁冰寒',18)

#继承
class Base:
    def f1(self):
        print('f1')

class Bar(Base):
    def f2(self):
        print('f2')

obj=Bar()
obj.f1()
#多态
class Foo(object):
    def func(self,arg):
        v=arg[0]
        print(v)
obj=Foo()
obj.func('梁冰寒')
obj.func([22,33,55])

'''
#2.什么是鸭子模型？
'''
对于一个函数而言，python对于参数的类型不会限制，那么传入参数时就可以是各种类型，在函数中如果例如有索引功能，那么就是 
对于传入的参数做了一个限制（该参数的类型必须有索引功能），这就是鸭子模型，

'''
#3.列举面向对象中的类成员和对象成员。
'''
类成员：类变量、绑定方法、类方法、静态方法、属性
对象成员：实例变量
'''
#4.@classmethod和@staticmethod的区别?
'''
一个是类方法另一个是静态方法，
定义：
类方法：用@classmethod方法做装饰器，且至少有一个cls参数
静态方法：用@staticmethod方法做装饰器，参数无限制
调用：
类.方法直接调用
对象.方法也可以调用
'''
#5.Python中双下滑 __ 有什么作用？
'''
将公有参数或者共有方法变为私有参数或者私有方法
'''
#6.看代码写结果
'''
class Base:
    x = 1

obj = Base()


print(obj.x)  #1
obj.y = 123
print(obj.y)  #123
obj.x = 123
print(obj.x)  #123
print(Base.x)  #1
'''

#7.看代码写结果
'''
class Parent:
    x = 1

class Child1(Parent):
    pass

class Child2(Parent):
    pass

print(Parent.x,Child1.x,Child2.x)  #1 1 1
Child2.x = 2
print(Parent.x,Child1.x,Child2.x)  #1  1  2
Child1.x = 3
print(Parent.x,Child1.x,Child2.x)  #1, 3  2

'''
#8.看代码写结果
'''
class Foo(object):
    n1 = '武沛齐'
    n2 = '金老板'
    def __init__(self):
        self.n1 = '女神'

obj = Foo()
print(obj.n1)  #女神
print(obj.n2)  #金老板

'''
#9.看代码写结果【如果有错误，则标注错误即可，并且假设程序报错可以继续执行】
'''
class Foo(object):
    n1 = '武沛齐'
    def __init__(self,name):
        self.n2 = name
obj = Foo('太白')
print(obj.n1)  #武沛齐
print(obj.n2)  #太白

print(Foo.n1)  #武沛齐
print(Foo.n2)  #报错
'''
#10.看代码写结果【如果有错误，则标注错误即可，并且假设程序报错可以继续执行】
'''
class Foo(object):
    a1 = 1
    __a2 = 2

    def __init__(self,num):
        self.num = num
        # self.__salary = 1000

     def show_data(self):
         print(self.num+self.a1)

obj = Foo(666)

print(obj.num)  #666
print(obj.a1)  #1
print(obj.__salary)    #报错
print(obj.__a2)    #报错
print(Foo.a1)   #1
print(Foo.__a2) #报错
'''

#11.看代码写结果【如果有错误，则标注错误即可，并且假设程序报错可以继续执行】
'''
class Foo(object):
    a1 = 1

    def __init__(self, num):
        self.num = num

    def show_data(self):
        print(self.num + self.a1)


obj1 = Foo(666)   #
obj2 = Foo(999)
print(obj1.num)  #666
print(obj1.a1)   #1

obj1.num = 18
obj1.a1 = 99

print(obj1.num)  #18
print(obj1.a1)  #99

print(obj2.a1)  #1
print(obj2.num)#999
print(obj2.num)#999
print(Foo.a1)  #1
print(obj1.a1)#99
'''
#12.看代码写结果，注意返回值。
'''
class Foo(object):

    def f1(self):
        return 999

    def f2(self):
        v = self.f1()
        print('f2')
        return v

    def f3(self):
        print('f3')
        return self.f2()

    def run(self):
        result = self.f3()
        print(result)

obj = Foo()
v1 = obj.run()  #f3,f2  999
print(v1) #None
'''
#13.看代码写结果【如果有错误，则标注错误即可，并且假设程序报错可以继续执行】
'''
class Foo(object):

    def f1(self):
        print('f1')

    @staticmethod
    def f2():
        print('f2')
obj = Foo()
obj.f1()  #f1
obj.f2()  #f2

Foo.f1()#报错，该方法为绑定方法/普通方法，调用：对象.方法（） 而不是类.方法
Foo.f2() #f2
'''
#14.看代码写结果【如果有错误，则标注错误即可，并且假设程序报错可以继续执行】
'''
class Foo(object):

    def f1(self):
        print('f1')

    @classmethod
    def f2(cls):
        print('f2')
obj = Foo()
obj.f1() #f1
obj.f2()#f2

Foo.f1()  #报错  
Foo.f2()#f2
'''
#15.看代码写结果【如果有错误，则标注错误即可，并且假设程序报错可以继续执行】
'''
class Foo(object):

    def f1(self):
        print('f1')
        self.f2()
        self.f3()

    @classmethod
    def f2(cls):
          print('f2')

    @staticmethod
    def f3():
          print('f3')

obj = Foo()
obj.f1() #f1  f2  f3
'''
#16.看代码写结果【如果有错误，则标注错误即可，并且假设程序报错可以继续执行】
'''
class Base(object):
    @classmethod
    def f2(cls):
          print('f2')

    @staticmethod
    def f3():
          print('f3')

class Foo(Base):
    def f1(self):
        print('f1')
        self.f2()
        self.f3()

obj = Foo()
obj.f1()
'''
#17.看代码写结果
'''
class Foo(object):
    def __init__(self, num):
        self.num = num

v1 = [Foo for i in range(10)]
v2 = [Foo(5) for i in range(10)]
v3 = [Foo(i) for i in range(10)]

print(v1)#[Foo,Foo,Foo,Foo,Foo,Foo.....Foo]
print(v2)#[Foo(5),Foo(5),Foo(5),Foo(5),Foo(5),Foo(5),Foo(5),Foo(5),Foo(5),Foo(5)]   # 都代表Foo类实例化的对象内存地址
print(v3)#[Foo(0),Foo(1),Foo(2),Foo(3),Foo(4),Foo(5),Foo(6),Foo(7),Foo(8),Foo(9)]   # 都代表Foo类实例化的对象内存地址
'''

# 18.看代码写结果
'''
class StarkConfig(object):
    def __init__(self, num):
        self.num = num
    def changelist(self, request):
        print(self.num, request)


config_obj_list = [StarkConfig(1), StarkConfig(2), StarkConfig(3)]
for item in config_obj_list:
    print(item.num)#1,2,3
'''
#19.看代码写结果
'''
class StarkConfig(object):

    def __init__(self, num):
        self.num = num

    def changelist(self, request):
        print(self.num, request)


config_obj_list = [StarkConfig(1), StarkConfig(2), StarkConfig(3)]
for item in config_obj_list:
    item.changelist(666)#(1,666)  (2,666)  (3,666)

'''

#20.看代码写结果
'''
class Department(object):
    def __init__(self,title):
        self.title = title

class Person(object):
    def __init__(self,name,age,depart):
        self.name = name
        self.age = age
        self.depart = depart


d1 = Department('人事部')
d2 = Department('销售部')

p1 = Person('武沛齐',18,d1)
p2 = Person('alex',18,d1)
p3 = Person('安安',19,d2)

print(p1.name)  #武沛齐
print(p2.age)  #18
print(p3.depart)#实例化一个对象
print(p3.depart.title)#销售部
'''
#21.
'''
class Department(object):
    def __init__(self, title):
        self.title = title


class Person(object):
    def __init__(self, name, age, depart):
        self.name = name
        self.age = age
        self.depart = depart

    def message(self):
        msg = "我是%s,年龄%s,属于%s" % (self.name, self.age, self.depart.title)
        print(msg)


d1 = Department('人事部')
d2 = Department('销售部')

p1 = Person('武沛齐', 18, d1)
p2 = Person('alex', 18, d1)
p1.message()#我是武佩奇，年龄18属于人事部
p2.message()#我是alex,年龄18,属于人事部
'''

#21编写类完成以下的嵌套关系

"""
角色：学校、课程、班级
要求：
	1. 创建北京、上海、深圳三所学校。
	2. 创建课程
		北京有三种课程：Linux、Python、Go
		上海有两种课程：Linux、Python
		深圳有一种课程：Python
	3. 创建班级(班级包含：班级名称、开班时间、结课时间、班级人数)
		北京Python开设：21期、22期
		北京Linux开设：2期、3期
		北京Go开设：1期、2期
		上海Python开设：1期、2期
		上海Linux开设：2期
		深圳Python开设：1期、2期
"""


# class School:
#     def __init__(self,school_name):
#         self.school_name=school_name
#
# class Course:
#     def __init__(self,school,course_name):
#         self.school=school
#         self.course_name=course_name
#
# class Class_room(object):
#     def __init__(self,class_name,start_time,end_time,people_num):
#         self.class_name=class_name
#         self.start_time=start_time
#         self.end_time=end_time
#         self.people_num=people_num
#
#     def func(self):
#         data='班级名称：%s%s%s'%(self.course.school.school_name,self.Course.course_name,self.class_name)
#

class School(object):
    def __init__(self,address):
        self.address = address

class Curriculum(object):
    def __init__(self,school,subject):
        self.school = school
        self.subject = subject

class Classroom(object):
    def __init__(self,curriculum,name,start_time,end_time,peoper_num):
        self.curriculum = curriculum
        self.name = name
        self.start_time = start_time
        self.end_time = end_time
        self.people_num = peoper_num

    def func(self):
        data1 = '班级名称：%s%s%s，' % (self.curriculum.school.address, self.curriculum.subject, self.name,)
        date2 = '开班时间：%s，结课时间：%s，班级人数：%s' % (self.start_time,self.end_time,self.people_num)
        print(data1 + date2)

class Run(object):
    def beijing(self):
        s = School('北京')
        while True:
            print("""*-*-*-*北京校区课程*-*-*-*
1,Linux；2，Python；3，Go""")
            index = input('请选择课程序号(N返回上一层)：')
            if index.upper() == 'N':
                break
            elif index == '1':
                c = Curriculum(s, 'Linux')
                Classroom(c, '2期', '2017.3', '2017.8', 70).func()
                Classroom(c, '3期', '2017.10', '2018.3', 77).func()
            elif index == '2':
                c = Curriculum(s, 'Python')
                Classroom(c, '21期', '2019.3', '2019.8', 78).func()
                Classroom(c, '22期', '2019.10', '2020.3', 80).func()
            elif index == '3':
                c = Curriculum(s, 'Go')
                Classroom(c, '1期', '2018.3', '2018.8', 66).func()
                Classroom(c, '2期', '2018.10', '2019.3', 69).func()
            else:
                print('输入错误,请重新输入')

    def shanghai(self):
        s = School('上海')
        while True:
            print("""*-*-*-*上海校区课程*-*-*-*
1,Linux；2，Python""")
            index = input('请选择课程序号(N返回上一层)：')
            if index.upper() == 'N':
                break
            elif index == '1':
                c = Curriculum(s, 'Linux')
                Classroom(c, '2期', '2017.6', '2017.11', 75).func()
            elif index == '2':
                c = Curriculum(s, 'Python')
                Classroom(c, '1期', '2018.7', '2019.2', 73).func()
                Classroom(c, '2期', '2019.3', '2020.9', 86).func()
            else:
                print('输入错误,请重新输入')

    def shenzhen(self):
        s = School('深圳')
        print('*-*-*-*深圳校区课程*-*-*-*')
        c = Curriculum(s, 'Python')
        Classroom(c, '1期', '2018.4', '2018.10', 68).func()
        Classroom(c, '2期', '2018.12', '2019.5', 71).func()

while True:
    v = Run()
    print("""*-*-*-*老男孩*-*-*-*
1，北京；2，上海；3，深圳'""")
    info = {'1':v.beijing,'2':v.shanghai,'3':v.shenzhen}
    index = input('请选择校区序号(N退出)：')
    if index.upper() == 'N':
        break
    elif info.get(index):
        info.get(index)()
    else:
        print('输入错误,请重新输入')
